package org.jeecg.modules.mes.produce.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.mes.client.StockClient;
import org.jeecg.modules.mes.produce.entity.MesCommandbillInfo;
import org.jeecg.modules.mes.produce.entity.MesCommandbillPitem;
import org.jeecg.modules.mes.produce.entity.TurnProduceRecord;
import org.jeecg.modules.mes.produce.mapper.MesCommandbillPitemMapper;
import org.jeecg.modules.mes.produce.service.IMesCommandbillInfoService;
import org.jeecg.modules.mes.produce.service.IMesCommandbillPitemService;
import org.jeecg.modules.mes.produce.service.ITurnProduceRecordService;
import org.jeecg.modules.mes.storage.entity.MesMaterielOccupy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * @Description: 制造中心—制令单BOM项目
 * @Author: jeecg-boot
 * @Date: 2020-12-17
 * @Version: V1.0
 */
@Service
public class MesCommandbillPitemServiceImpl extends ServiceImpl<MesCommandbillPitemMapper, MesCommandbillPitem> implements IMesCommandbillPitemService {

    @Autowired
    private StockClient stockClient;
    @Autowired
    private IMesCommandbillInfoService mesCommandbillInfoService;
    @Autowired
    private ITurnProduceRecordService turnProduceRecordService;
    @Autowired
    private MesCommandbillPitemMapper mesCommandbillPitemMapper;

    /**
     * 制令单批量转产
     *
     * @param mobileType              转产编号 268
     * @param mesCommandbillPitemList 原制令单信息
     * @param newCode                 需要转的制令单code
     * @return
     */
    @Transactional
    public boolean wholeChangeProduce(String mobileType, String newCode, List<MesCommandbillPitem> mesCommandbillPitemList) {

        String mobileCode = "268";
        //268 制令单批量转产
        if (mobileCode.equals(mobileType)) {
            //原制令单bom表信息
            if (mesCommandbillPitemList.size() != 0) {
                MesCommandbillInfo commandbill = mesCommandbillInfoService.getById(mesCommandbillPitemList.get(0).getCommandbillId());//原制令单
                //转产记录表
                for (MesCommandbillPitem commandbillPitem : mesCommandbillPitemList) {//遍历原有制令单bom信息
                    String mCode = commandbillPitem.getMaterielCode();//原有物料料号
                    //原制令单的数量信息归纳
                    BigDecimal deliveryNum = new BigDecimal(commandbillPitem.getDeliveryNum());//已发料数量
                    BigDecimal consumeNum = new BigDecimal(commandbillPitem.getConsumeNum());//已消耗数量
                    BigDecimal withdrawNum = new BigDecimal(commandbillPitem.getWithdrawNum());//已退料料数量
                    if (StringUtils.isBlank(commandbillPitem.getTransformNum())) {
                        commandbillPitem.setTransformNum("0");
                    }
                    BigDecimal transformNum = new BigDecimal(commandbillPitem.getTransformNum());//已转产数量
                    BigDecimal shiyongNum = consumeNum.add(withdrawNum).add(transformNum);//已使用数量=已消耗数量+已退料料数量+已转产数量
                    BigDecimal adviceNum = deliveryNum.subtract(shiyongNum);//建议转产数量=已发料数量-已使用数量
                    BigDecimal realNum = new BigDecimal(commandbillPitem.getVirtualNum());//实际转产数量
                    if (realNum.compareTo(adviceNum) == 1) {
                        throw new RuntimeException("原制令单物料" + commandbillPitem.getMaterielCode() + "转产数量不对！请检查！");
                    }
                    System.out.println("实际转产数量:" + realNum);
                    //执行bom的转产操作
                    //通过转产制令单号和物料料号，获取转产制令单Bom的数据
                    QueryWrapper<MesCommandbillPitem> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("commandbill_code", newCode).eq("materiel_code", mCode);
                    MesCommandbillPitem pitem = getOne(queryWrapper);

                    MesCommandbillInfo commandbill2 = mesCommandbillInfoService.getById(pitem.getCommandbillId());//转产制令单
                    //转产记录表
                    TurnProduceRecord turnProduceRecord = new TurnProduceRecord();
                    //没有查询出来的进入退料操作
                    if (pitem != null) {

                        //根据原制令单上料剩余的数量，复制一份上料数据,转产上料数量
                        String wareNum = stockClient.updateCommandbill(commandbillPitem.getCommandbillId(), shiyongNum.toString(), mCode, pitem.getId(), pitem.getCommandbillId());
                        if (StringUtils.isBlank(pitem.getUnglazeNum())) {
                            pitem.setUnglazeNum("0");
                        }
                        if (StringUtils.isBlank(wareNum)) {
                            wareNum = "0";
                        }
                        BigDecimal punglazeNum = new BigDecimal(pitem.getUnglazeNum());
                        BigDecimal pdeliveryNum = new BigDecimal(pitem.getDeliveryNum());
                        BigDecimal unglazeNowNum = punglazeNum.add(new BigDecimal(wareNum));
                        BigDecimal pdeliveryNowNum = pdeliveryNum.add(realNum);
                        pitem.setUnglazeNum(unglazeNowNum.toString());
                        pitem.setDeliveryNum(pdeliveryNowNum.toString());
                        System.out.println("pitem:" + pitem);
                        System.out.println("commandbillPitem:" + commandbillPitem);
                        //进入转产操作
                        if (StringUtils.isNotBlank(mCode)
                                && StringUtils.isNotBlank(commandbillPitem.getProorderId())
                                && StringUtils.isNotBlank(pitem.getProorderId())) {
                            //通过订单id与物料料号，查询领料表信息
                            String produceId = commandbillPitem.getProorderId();//原有制令单关联的生产订单id
                            String orderId = pitem.getProorderId();//转产制令单关联的生产订单id
                            if (!produceId.equals(orderId)) {
                                MesMaterielOccupy materielOccupy = stockClient.queryByIdAndmCodeUpdateTransformNum(produceId, mCode, realNum.toString());
                                System.out.println("原有制令单Bom表的转产数量:" + materielOccupy);
                                if (materielOccupy != null) {
                                    //更新原有制令单Bom表的转产数量
                                    BigDecimal transformNewNum = realNum.add(transformNum);
                                    commandbillPitem.setTransformNum(transformNewNum.toString());
                                    this.updateById(commandbillPitem);
                                } else {
                                    throw new RuntimeException("没有找到原有制令单的物料领用信息！请检查！");
                                }

                                //更新转产生产单发料数量
                                MesMaterielOccupy mesMaterielOccupy = stockClient.queryByIdAndmCodeUpdateSendNum(orderId, mCode, pitem.getDeliveryNum());
                                System.out.println("==更新转产生产单发料数量==" + mesMaterielOccupy);
                                if (mesMaterielOccupy != null) {
                                    //更新转产制令单Bom表的发料数量
                                    pitem.setDeliveryNum(pdeliveryNowNum.toString());
                                    if (pdeliveryNowNum.compareTo(new BigDecimal(pitem.getRequireNum())) > -1) {//发料数量大于已发数量则改状态
                                        pitem.setIfDelivery("已发料");
                                    }
                                    if (unglazeNowNum.compareTo(new BigDecimal(pitem.getRequireNum())) > -1) {//上料数量大于已发数量则改状态
                                        pitem.setIfGlaze("已上料");
                                    }
                                    this.updateById(pitem);
                                    System.out.println("==更新转产生产单发料数量==" + pitem);
                                } else {
                                    throw new RuntimeException("没有找到转产制令单的物料领用信息！请检查！");
                                }
                            } else {
                                throw new RuntimeException("两个的生产订单相同，不能转产！");
                               /* BigDecimal transNewnum = transformNum.add(realNum);//新的转产数量 = 已转产数量 + 转产数量
                                commandbillPitem.setTransformNum(transNewnum.toString());
                                this.updateById(commandbillPitem);

                                BigDecimal originalNum = new BigDecimal(pitem.getDeliveryNum());//原有的数量
                                BigDecimal deliveryNewnum = originalNum.add(realNum);//新的发料数量 = 原有数量 + 转产数量
                                pitem.setDeliveryNum(deliveryNewnum.toString());
                                pitem.setUnglazeNum(wareNum);//加上上一个制令单转产的上料数量
                                this.updateById(pitem);*/
                            }
                        } else {
                            throw new RuntimeException("制令单Bom表里没有查询到订单id和物料料号！请检查！");
                        }

                        turnProduceRecord.setState("转产");
                    } else {
                        if (StringUtils.isNotBlank(commandbillPitem.getProorderId())) {
                            //制令单退料时，将退料数量记录在物料领用表，并返回到库存上
                            MesMaterielOccupy materielOccupy = stockClient.queryByIdAndmCodeUpdatewithdrawNum(commandbillPitem.getProorderId(), mCode, realNum.toString());

                            if (materielOccupy != null) {
                                //返还库存
                                stockClient.updateMcodeNum(commandbillPitem.getMaterielCode(), realNum.toString());
                                //更新原有制令单Bom表的退料数量
                                commandbillPitem.setWithdrawNum(materielOccupy.getWithdrawNum());
                                updateById(commandbillPitem);
                            } else {
                                throw new RuntimeException("没有找到原有制令单的物料领用信息！请检查！");
                            }
                        } else {
                            throw new RuntimeException("制令单Bom表里没有查询到生产订单id！请检查！");
                        }
                        //todo 退料改关联物料上过料的发料状态改为未发料
                        //退料记录
                        turnProduceRecord.setState("退料");
                    }
                    turnProduceRecord.setCommandbillId(commandbillPitem.getCommandbillId());
                    turnProduceRecord.setCommandbillCode(commandbillPitem.getCommandbillCode());
                    turnProduceRecord.setMechanismCode(commandbill.getMechanismCode());
                    turnProduceRecord.setMechanismName(commandbill.getMechanismName());
                    turnProduceRecord.setZcommandbillId(pitem.getCommandbillId());
                    turnProduceRecord.setZcommandbillCode(pitem.getCommandbillCode());
                    turnProduceRecord.setZmechanismCode(commandbill2.getMechanismCode());
                    turnProduceRecord.setZmechanismName(commandbill2.getMechanismName());
                    turnProduceRecord.setProductCode(commandbillPitem.getMaterielCode());
                    turnProduceRecord.setProductName(commandbillPitem.getMaterielName());
                    turnProduceRecord.setSurplusNum(realNum.toString());
                    turnProduceRecordService.save(turnProduceRecord);
                }
                //修改原制令单发料、上料为已完成
//                commandbill.setDeliveryState("已完成");
//                commandbill.setGlazeState("已完成");
                commandbill.setChangeState("1");
                mesCommandbillInfoService.updateById(commandbill);
            } else {
                throw new RuntimeException("没有找到制令单BOM的数据！请检查！");
            }
        } else {
            throw new RuntimeException("制令单批量转产时移动编号不等于268！请检查");
        }
        return true;
    }

    /**
     * 远程调用，根据制令单发料数量修改生产订单状态
     */
    @Override
    public boolean checkProductStatusByCommandBillId(String commandBillId) {
        QueryWrapper<MesCommandbillPitem> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("commandbill_id", commandBillId);
        queryWrapper.eq("delivery_num", "0");
        List<MesCommandbillPitem> mesCommandbillPitemList = mesCommandbillPitemMapper.selectList(queryWrapper);
        if(mesCommandbillPitemList.size()==0){
            return true;//发货完成
        }
        return false;//发货未完成
    }

	@Override
	public List<MesCommandbillPitem> selectByMainId(String mainId) {
		return mesCommandbillPitemMapper.selectByMainId(mainId);
	}
}
